'use strict';

const dataConst = require('../constant/data-const');

const Service = require('egg').Service;

class MemberCoupleService extends Service {
    async checkTargetCoupleInviteSrv(userId, targetUserId) {
        const { app } = this;

        const recResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: targetUserId,
                target_user_id: userId
            }
        });

        if (recResult) {
            return recResult.state === dataConst.coupleStateType.invite.value;
        }

        return null;
    }

    async sendCoupleInviteSrv(userId, targetUserId) {
        const { app } = this;

        const recResult = await app.model.MemberCouple.findOne({
            where: {
                target_user_id: targetUserId,
                state: dataConst.coupleStateType.accept.value
            }
        });

        if (recResult) {
            if (recResult.user_id === parseInt(userId)) {
                throw new Error('你们已经是CP啦。');
            } else {
                throw new Error('TA已经有CP小伙伴啦。');
            }
        }

        const sendResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: userId
            }
        });

        if (sendResult) {
            if (sendResult.target_user_id === parseInt(targetUserId)) {
                switch (sendResult.state) {
                    case dataConst.coupleStateType.cancel.value:
                    case dataConst.coupleStateType.reject.value:
                        sendResult.state = dataConst.coupleStateType.invite.value;
                        break;

                    case dataConst.coupleStateType.invite.value:
                        throw new Error('你已经向该会员发出CP邀请啦。');

                    case dataConst.coupleStateType.accept.value:
                        throw new Error('你们已经是CP啦。');
                }
            } else {
                switch (sendResult.state) {
                    case dataConst.coupleStateType.cancel.value:
                    case dataConst.coupleStateType.reject.value:
                        sendResult.state = dataConst.coupleStateType.invite.value;
                        sendResult.target_user_id = targetUserId;
                        break;

                    case dataConst.coupleStateType.invite.value:
                        throw new Error('你已经有其他CP邀请啦，请先取消才能重新邀请。');

                    case dataConst.coupleStateType.accept.value:
                        throw new Error('你已经有CP小伙伴啦，请先解绑才能重新邀请。');
                }
            }

            await app.model.MemberCouple.update({
                state: dataConst.coupleStateType.cancel.value
            }, {
                where: {
                    user_id: targetUserId,
                    target_user_id: userId,
                    state: dataConst.coupleStateType.reject.value
                }
            });

            return await sendResult.save();
        } else {
            await app.model.MemberCouple.update({
                state: dataConst.coupleStateType.cancel.value
            }, {
                where: {
                    user_id: targetUserId,
                    target_user_id: userId,
                    state: dataConst.coupleStateType.reject.value
                }
            });

            return await app.model.MemberCouple.create({
                user_id: userId,
                target_user_id: targetUserId,
                state: dataConst.coupleStateType.invite.value
            });
        }
    }

    async receiveCoupleInviteSrv(userId, targetUserId) {
        const { app } = this;

        const sendResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: userId,
                target_user_id: targetUserId
            }
        });

        if (sendResult) {
            if (sendResult.state === dataConst.coupleStateType.accept.value) {
                throw new Error('你们已经是CP啦。');
            }
        }

        const recResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: targetUserId,
                target_user_id: userId
            }
        });

        if (recResult) {
            if (recResult.state === dataConst.coupleStateType.accept.value) {
                throw new Error('你们已经是CP啦。');
            } else {
                await app.model.MemberCouple.update({
                    state: dataConst.coupleStateType.reject.value
                }, {
                    where: {
                        user_id: {
                            $ne: targetUserId
                        },
                        target_user_id: userId,
                        state: dataConst.coupleStateType.invite.value
                    }
                });

                await app.model.MemberCouple.update({
                    state: dataConst.coupleStateType.reject.value
                }, {
                    where: {
                        user_id: {
                            $ne: userId
                        },
                        target_user_id: targetUserId,
                        state: dataConst.coupleStateType.invite.value
                    }
                });

                recResult.state = dataConst.coupleStateType.accept.value;
                return await recResult.save();
            }
        } else {
            throw new Error('没有CP邀请记录！');
        }
    }

    async cancelCoupleInviteSrv(userId, targetUserId) {
        const { app } = this;

        const inviteResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: userId,
                target_user_id: targetUserId,
                state: dataConst.coupleStateType.invite.value
            }
        });

        if (inviteResult) {
            inviteResult.state = dataConst.coupleStateType.cancel.value;
            return await inviteResult.save();
        } else {
            throw new Error('没有CP邀请记录');
        }
    }

    async rejectCoupleInviteSrv(userId, targetUserId) {
        const { app } = this;

        const inviteResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: targetUserId,
                target_user_id: userId,
                state: dataConst.coupleStateType.invite.value
            }
        });

        if (inviteResult) {
            inviteResult.state = dataConst.coupleStateType.reject.value;
            return await inviteResult.save();
        } else {
            throw new Error('没有CP邀请记录');
        }
    }

    async releaseCoupleRelationSrv(userId, targetUserId) {
        const { app } = this;

        const sendResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: userId,
                target_user_id: targetUserId,
                state: dataConst.coupleStateType.accept.value
            }
        });

        if (sendResult) {
            sendResult.state = dataConst.coupleStateType.cancel.value;
            await sendResult.save();
            return true;
        }

        const recResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: targetUserId,
                target_user_id: userId,
                state: dataConst.coupleStateType.accept.value
            }
        });

        if (recResult) {
            recResult.state = dataConst.coupleStateType.cancel.value;
            await recResult.save();
            return true;
        }
    }

    async checkCoupleBindStatusSrv(userId) {
        const { app } = this;

        return app.model.MemberCouple.findOne({
            where: {
                $or: [
                    {
                        user_id: userId
                    },
                    {
                        target_user_id: userId
                    }
                ],
                state: dataConst.coupleStateType.accept.value
            }
        });
    }

    async getCoupleBindDateTime(userId, targetUserId) {
        const { ctx } = this;

        const queryString =
            `select
                if(mc.updated_at is not null, timestampdiff(day, mc.updated_at, curdate()) + 1, 0) as bindDate
                from tbl_member_couple mc
                where true
                and ((mc.user_id = :userId and mc.target_user_id = :targetUserId)
                or (mc.target_user_id = :userId and mc.user_id = :targetUserId))
                and mc.state = :state`;

        const paramsData = {
            userId,
            targetUserId,
            state: dataConst.coupleStateType.accept.value
        };

        const [result] = await ctx.helper.sqlQuery(queryString, paramsData);
        if (result) {
            const { bindDate } = result;
            return bindDate;
        } else {
            return null;
        }
    }

    async receiveCoupleInviteListSrv({userId, limit, offset}) {
        const { ctx } = this;

        let queryString =
            `select
                mc.id, mc.state, mc.invite_note, mc.updated_at
                , usr.id as user_id, usr.nickname
                , date(usr.birthday) as birthday
                , timestampdiff(year, usr.birthday, curdate()) as age
                , if(isnull(usr.avatar) || length(trim(usr.avatar)) < 1, null, concat(:serverUrl, :avatarPath, usr.id, '/', usr.avatar)) as avatar_url
                from tbl_member_couple mc
                left join tbl_user usr
                on mc.user_id = usr.id
                where true
                and mc.state = :coupleState
                and usr.state = :state
                and mc.target_user_id = :userId`;

        const paramsData = {
            serverUrl: dataConst.serverUrl,
            avatarPath: dataConst.avatarPath,
            coupleState: dataConst.coupleStateType.invite.value,
            state: dataConst.stateType.active,
            userId
        };

        queryString += ` order by mc.updated_at desc`;

        return await ctx.helper.sqlQueryCount(queryString, paramsData, limit, offset);
    }

    async sendCoupleInviteListSrv({userId, limit, offset}) {
        const { ctx } = this;

        let queryString =
            `select
                mc.id, mc.state, mc.invite_note, mc.updated_at
                , usr.id as user_id, usr.nickname
                , date(usr.birthday) as birthday
                , timestampdiff(year, usr.birthday, curdate()) as age
                , if(isnull(usr.avatar) || length(trim(usr.avatar)) < 1, null, concat(:serverUrl, :avatarPath, usr.id, '/', usr.avatar)) as avatar_url
                from tbl_member_couple mc
                left join tbl_user usr
                on mc.target_user_id = usr.id
                where true
                and (mc.state = :inviteState or mc.state = :rejectState)
                and usr.state = :state
                and mc.user_id = :userId`;

        const paramsData = {
            serverUrl: dataConst.serverUrl,
            avatarPath: dataConst.avatarPath,
            inviteState: dataConst.coupleStateType.invite.value,
            rejectState: dataConst.coupleStateType.reject.value,
            state: dataConst.stateType.active,
            userId
        };

        queryString += ` order by mc.updated_at desc`;

        return await ctx.helper.sqlQueryCount(queryString, paramsData, limit, offset);
    }

    async getMemberCoupleRelationSrv(userId, targetUserId) {
        const { app } = this;

        const sendResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: userId,
                target_user_id: targetUserId,
                state: dataConst.coupleStateType.accept.value
            }
        });

        if (sendResult) {
            return true;
        }

        const recResult = await app.model.MemberCouple.findOne({
            where: {
                user_id: targetUserId,
                target_user_id: userId,
                state: dataConst.coupleStateType.accept.value
            }
        });

        if (recResult) {
            return true;
        }
    }

    async getCoupleInviteCountSrv(userId) {
        const { app } = this;

        return await app.model.MemberCouple.count({
            where: {
                target_user_id: userId,
                state: dataConst.coupleStateType.invite.value
            }
        });
    }
}

module.exports = MemberCoupleService;
